package com.bcu.calculus.utils;

import cn.hutool.crypto.asymmetric.RSA;
import com.bcu.calculus.entity.TokenInfo;
import com.bcu.calculus.entity.User;
import com.bcu.calculus.exception.InvalidTokenException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private static RSA rsa = new RSA(RSAUtils.getKeyFromFile("key.pri"), RSAUtils.getKeyFromFile("key.pub"));

    public static String createJwtToken(User u) {

        Map claims = new HashMap<>();
        claims.put("userId", u.getUserId());
        claims.put("userType", u.getUserType());
        claims.put("userName", u.getUserinfo().getUserName());
        claims.put("userBranch", u.getUserinfo().getUserBranch());
        return Jwts.builder()
                .setClaims(claims)
                .setExpiration(new Date(new Date().getTime() + 2 * 60 * 60 * 1000))
                .setSubject(u.getUserId())
                .signWith(rsa.getPrivateKey())
                .compact();
    }

    public static Claims resolveToken(String token) throws Exception {
        Jws<Claims> jws;
        jws = Jwts.parserBuilder()  // (1)
                .setSigningKey(rsa.getPublicKey())         // (2)
                .build()                    // (3)
                .parseClaimsJws(token); // (4)
        return jws.getBody();
        // we can safely trust the JWT
    }

    public static TokenInfo getTokenInfo(String token) {
        try {
            Claims claims = resolveToken(token);
            TokenInfo tokenInfo = new TokenInfo();
            tokenInfo.setUserId((String) claims.get("userId"));
            tokenInfo.setUserType((String) claims.get("userType"));
            tokenInfo.setUserName((String) claims.get("userName"));
            tokenInfo.setUserBranch((Integer) claims.get("userBranch"));
            tokenInfo.setUserReconsider((Integer) claims.get("userReconsider"));
            return tokenInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new InvalidTokenException();
        }

    }
}

